class WebSocketClient {
  // 连接状态常量
  static CONNECTING = 0
  static OPEN = 1
  static CLOSING = 2
  static CLOSED = 3

  constructor(options = {}) {
    // 基础配置
    this.url = options.url || ''
    this.reconnectLimit = options.reconnectLimit || 3 // 最大重连次数
    this.reconnectCount = 0 // 当前重连次数
    this.heartbeatInterval = options.heartbeatInterval || 30000 // 心跳间隔(ms)
    this.heartbeatTimeout = options.heartbeatTimeout || 10000 // 心跳超时时间(ms)

    // 状态管理
    this.readyState = WebSocketClient.CLOSED
    this.socketTask = null
    this.events = {}
    this.messageQueue = []

    // 定时器
    this.heartbeatTimer = null
    this.heartbeatTimeoutTimer = null
  }

  // 事件监听
  on(event, listener) {
    if (!this.events[event]) this.events[event] = []
    this.events[event].push(listener)
  }

  // 移除事件监听
  off(event, listener) {
    if (!this.events[event]) return
    this.events[event] = this.events[event].filter(l => l !== listener)
  }

  // 触发事件
  emit(event, ...args) {
    if (!this.events[event]) return
    this.events[event].forEach(listener => listener(...args))
  }

  // 创建连接
  connect() {
    if (this.readyState !== WebSocketClient.CLOSED) return

    this.readyState = WebSocketClient.CONNECTING
    this.socketTask = wx.connectSocket({ url: this.url })

    // 监听连接打开
    this.socketTask.onOpen(() => {
      this.readyState = WebSocketClient.OPEN
      this.reconnectCount = 0
      this.emit('open')
      this._startHeartbeat()
      this._flushMessageQueue()
      console.log('WebSocket 连接已打开')
    })

    // 监听消息接收
    this.socketTask.onMessage((res) => {
      this.emit('message', res.data)
      this._resetHeartbeat()
    })

    // 监听错误
    this.socketTask.onError((err) => {
      this.emit('error', err)
      console.error('WebSocket 错误:', err)
    })

    // 监听关闭
    this.socketTask.onClose((res) => {
      this.readyState = WebSocketClient.CLOSED
      this._stopHeartbeat()
      this.emit('close', res)
      console.log('WebSocket 连接关闭，代码:', res.code)
      this._handleReconnect()
    })

    // 监听连接失败
    this.socketTask.onFail((err) => {
      this.readyState = WebSocketClient.CLOSED
      this.emit('error', err)
      console.error('WebSocket 连接失败:', err)
      this._handleReconnect()
    })
  }

  // 发送消息
  send(data) {
    if (typeof data !== 'string') {
      data = JSON.stringify(data)
    }

    if (this.readyState === WebSocketClient.OPEN) {
      this.socketTask.send({
        data,
        success: () => console.log('消息发送成功:', data),
        fail: (err) => {
          console.error('消息发送失败，加入队列:', err)
          this.messageQueue.push(data)
        }
      })
    } else {
      console.warn('连接未就绪，消息加入队列:', data)
      this.messageQueue.push(data)
      if (this.readyState === WebSocketClient.CLOSED) {
        this.connect()
      }
    }
  }

  // 关闭连接
  close(code = 1000, reason = '正常关闭') {
    if (this.readyState === WebSocketClient.CLOSED) return

    this.readyState = WebSocketClient.CLOSING
    this.reconnectCount = this.reconnectLimit // 阻止重连
    this.socketTask?.close({ code, reason })
    this._stopHeartbeat()
    this.messageQueue = []
  }

  // 检查连接状态
  isConnected() {
    return this.readyState === WebSocketClient.OPEN
  }

  // 心跳管理
  _startHeartbeat() {
    this._stopHeartbeat()

    this.heartbeatTimer = setTimeout(() => {
      this.send(JSON.stringify({ type: 'ping' }))

      // 设置心跳超时检测
      this.heartbeatTimeoutTimer = setTimeout(() => {
        console.error('心跳超时，主动断开连接')
        this.close(1008, '心跳超时')
      }, this.heartbeatTimeout)
    }, this.heartbeatInterval)
  }

  // 重置心跳计时器
  _resetHeartbeat() {
    clearTimeout(this.heartbeatTimer)
    clearTimeout(this.heartbeatTimeoutTimer)
    this._startHeartbeat()
  }

  // 停止心跳计时器
  _stopHeartbeat() {
    clearTimeout(this.heartbeatTimer)
    clearTimeout(this.heartbeatTimeoutTimer)
  }

  // 重连管理（指数退避策略）
  _handleReconnect() {
    if (this.reconnectCount < this.reconnectLimit) {
      this.reconnectCount++
      const delay = Math.min(1000 * Math.pow(2, this.reconnectCount), 30000) // 指数退避，最大30秒
      console.log(`尝试第 ${this.reconnectCount} 次重连，延迟 ${delay}ms`)
      setTimeout(() => this.connect(), delay)
    } else {
      this.emit('reconnect_failed')
      console.error('已达到最大重连次数，停止重连')
    }
  }

  // 发送队列消息
  _flushMessageQueue() {
    while (this.messageQueue.length > 0 && this.isConnected()) {
      const message = this.messageQueue.shift()
      this.send(message)
    }
  }
}

export const wsClient = new WebSocketClient();